<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>React Component</title>
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/prismjs@1.6.0/themes/prism-tomorrow.css"/>
    <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
      background: linear-gradient(to bottom, hsl(0, 0%, 100%) 400px, hsl(0, 0%, 95%) 500px);
      margin: 20px;
    }
    body > *:not(.nav) {
      max-width: 800px;
      margin-left: auto;
      margin-right: auto;
      box-sizing: border-box;
    }
    pre {
      color: hsl(0, 0%, 90%);
      background: hsl(0, 0%, 10%);
      padding: 10px;
      border-radius: 6px;
      margin-bottom: 0;
    }
    pre.render-js-code {
      border-bottom-right-radius: 0px;
      border-bottom-left-radius: 0px;
    }
    .render-js {
      background: white;
      border: 1px solid hsl(0, 0%, 10%);
      padding: 10px;
      border-bottom-right-radius: 6px;
      border-bottom-left-radius: 6px;
    }
    .render-js:after {
      clear: both;
    }
    h1 { text-transform: uppercase;}
    h1, h1 + p {
      text-align: center
    }
    h1 + p > img {
      box-shadow: 0px 2px 20px hsla(0, 0%, 0%, 0.25);
      border-radius: 50%;
    }
    code {
      font-family: "SF Mono", "Monaco", "Inconsolata", "Fira Mono", "Droid Sans Mono", "Source Code Pro", monospace;
    }
    .nav {
      display: flex;
      justify-content: space-between;
      font-size: 80%;
      background: hsl(0, 0%, 10%);
      color: white;
      margin: -20px -20px 0px -20px;
      padding: 10px;
      text-transform: uppercase;
    }
    .nav a {
      text-decoration: none;
      color: inherit;
      transition: color 200ms ease;
      display: inline-block;
    }
    .nav a:hover {
      color: hsl(0, 0%, 80%);
    }
    .external-links a:not(:last-child) {
      padding: 0 5px;
    }
    h2 {
      text-transform: uppercase;
      border-bottom: solid 1px #ccc;
      padding-bottom: 5px;
      margin-top: 50px;
    }
    h2, h3, h4 {
      position: relative;
    }
    h3 {
      margin-top: 2em;
      font-size: 125%;
    }

    .header-anchor {
      position: absolute;
      left: -1em;
      color: #ccc;
      text-decoration: none;
      font-weight: normal;
      font-size: 80%;
    }
    </style>
  </head>
  <body>
    <nav class="nav">
      <div>
        <a href="https://github.com/ryanflorence">ryan florence</a> / <a href="https://github.com/ryanflorence/react-component-component">React Component Component</a>
      </div>
      <div class="external-links">
        <a href="https://workshop.me">Workshops</a>
        <a href="https://totalreact.com">Online Courses</a>
        <a href="https://twitter.com/ryanflorence">Twitter</a>
        <a href="https://github.com/ryanflorence/react-component-component">Github</a>
      </div>
    </nav> <h1 id="react-component-component"><a class="header-anchor" href="#react-component-component" aria-hidden="true">#</a> React Component ... Component</h1>
<h2 id="what"><a class="header-anchor" href="#what" aria-hidden="true">#</a> What?</h2>
<p>Declarative version of React.Component.</p>
<h2 id="why"><a class="header-anchor" href="#why" aria-hidden="true">#</a> Why?</h2>
<p>Because sometimes you want a lifecycle or some state but don't want to create a new component. Also, this stuff is composable as heck.</p>
<h2 id="installation"><a class="header-anchor" href="#installation" aria-hidden="true">#</a> Installation</h2>
<pre><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> react-component-component
<span class="token comment" spellcheck="true"># or</span>
yarn add react-component-component
</code></pre>
<p>And then import it:</p>
<pre><code class="language-js"><span class="token comment" spellcheck="true">// using es modules</span>
<span class="token keyword">import</span> Component <span class="token keyword">from</span> <span class="token string">"react-component-component"</span><span class="token punctuation">;</span>

<span class="token comment" spellcheck="true">// common.js</span>
<span class="token keyword">const</span> Component <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"react-component-component"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment" spellcheck="true">// AMD</span>
<span class="token comment" spellcheck="true">// I've forgotten but it should work.</span>
</code></pre>
<p>Or use script tags and globals.</p>
<pre><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>https://unpkg.com/react-component-component<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
</code></pre>
<p>And then grab it off the global like so:</p>
<pre><code class="language-js"><span class="token keyword">const</span> Component <span class="token operator">=</span> ReactComponentComponent<span class="token punctuation">;</span>
</code></pre>
<h2 id="how"><a class="header-anchor" href="#how" aria-hidden="true">#</a> How?</h2>
<p>Let's say you want some async data but don't want to make a whole new component just for the lifecycles to get it:</p>
<pre class="render-js-code"><code class="jsx"><span class="token comment" spellcheck="true">// import Component from 'react-component-component'</span>
<span class="token keyword">const</span> Component <span class="token operator">=</span> ReactComponentComponent<span class="token punctuation">;</span>

ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span>Let's <span class="token keyword">get</span> some gists<span class="token operator">!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Component</span>
      <span class="token attr-name">initialState</span><span class="token script language-javascript"><span class="token punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> gists<span class="token punctuation">:</span> <span class="token keyword">null</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span>
      <span class="token attr-name">didMount</span><span class="token script language-javascript"><span class="token punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">{</span> setState <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span>
        <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">"https://api.github.com/gists"</span><span class="token punctuation">)</span>
          <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>res <span class="token operator">=</span><span class="token operator">></span> res<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
          <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>gists <span class="token operator">=</span><span class="token operator">></span> <span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> gists <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span></span><span class="token attr-name">}</span>
    <span class="token punctuation">></span></span>
      <span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">{</span> state <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span>
        state<span class="token punctuation">.</span>gists <span class="token operator">?</span> <span class="token punctuation">(</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span>
            <span class="token punctuation">{</span>state<span class="token punctuation">.</span>gists<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>gist <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">(</span>
              <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token punctuation">=</span><span class="token punctuation">{</span>gist<span class="token punctuation">.</span>id<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>gist<span class="token punctuation">.</span>description<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
            <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
        <span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token punctuation">(</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>Loading<span class="token operator">...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
        <span class="token punctuation">)</span>
      <span class="token punctuation">}</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Component</span><span class="token punctuation">></span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">,</span>
  DOM_NODE
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<div id="render-2h2q3cgjmvo" class="render-js"></div>
<script type="text/babel">
(function() { var DOM_NODE = document.getElementById("render-2h2q3cgjmvo");
// import Component from 'react-component-component'
const Component = ReactComponentComponent;

ReactDOM.render(
  <div>
    <h2>Let's get some gists!</h2>
    <Component
      initialState={{ gists: null }}
      didMount={({ setState }) => {
        fetch("https://api.github.com/gists")
          .then(res => res.json())
          .then(gists => setState({ gists }));
      }}
    >
      {({ state }) =>
        state.gists ? (
          <ul>
            {state.gists.map(gist => (
              <li key={gist.id}>{gist.description}</li>
            ))}
          </ul>
        ) : (
          <div>Loading...</div>
        )
      }
    </Component>
  </div>,
  DOM_NODE
);

})()</script>

<p>Or maybe you need a little bit of state but an entire component
seems a bit heavy:</p>
<pre class="render-js-code"><code class="jsx"><span class="token comment" spellcheck="true">// import Component from 'react-component-component'</span>
<span class="token keyword">const</span> Component <span class="token operator">=</span> ReactComponentComponent<span class="token punctuation">;</span>

ReactDOM<span class="token punctuation">.</span><span class="token function">render</span><span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Component</span> <span class="token attr-name">initialState</span><span class="token script language-javascript"><span class="token punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> count<span class="token punctuation">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
    <span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">{</span> setState<span class="token punctuation">,</span> state <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span>Every app needs a counter<span class="token operator">!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
          <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span>
            <span class="token function">setState</span><span class="token punctuation">(</span>state <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> count<span class="token punctuation">:</span> state<span class="token punctuation">.</span>count <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
          <span class="token punctuation">}</span></span>
        <span class="token punctuation">></span></span>
          <span class="token operator">-</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">></span></span> <span class="token punctuation">{</span>state<span class="token punctuation">.</span>count<span class="token punctuation">}</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
          <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span>
            <span class="token function">setState</span><span class="token punctuation">(</span>state <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> count<span class="token punctuation">:</span> state<span class="token punctuation">.</span>count <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
          <span class="token punctuation">}</span></span>
        <span class="token punctuation">></span></span>
          <span class="token operator">+</span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span>
    <span class="token punctuation">)</span><span class="token punctuation">}</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Component</span><span class="token punctuation">></span></span><span class="token punctuation">,</span>
  DOM_NODE
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<div id="render-edlakmlmnmg" class="render-js"></div>
<script type="text/babel">
(function() { var DOM_NODE = document.getElementById("render-edlakmlmnmg");
// import Component from 'react-component-component'
const Component = ReactComponentComponent;

ReactDOM.render(
  <Component initialState={{ count: 0 }}>
    {({ setState, state }) => (
      <div>
        <h2>Every app needs a counter!</h2>
        <button
          onClick={() =>
            setState(state => ({ count: state.count - 1 }))
          }
        >
          -
        </button>
        <span> {state.count} </span>
        <button
          onClick={() =>
            setState(state => ({ count: state.count + 1 }))
          }
        >
          +
        </button>
      </div>
    )}
  </Component>,
  DOM_NODE
);

})()</script>

<h2 id="props"><a class="header-anchor" href="#props" aria-hidden="true">#</a> Props</h2>
<p>You know all of these already:</p>
<ul>
<li><code>didMount({ state, setState, props, forceUpdate })</code></li>
<li><code>shouldUpdate({ state, props, nextProps, nextState })</code></li>
<li><code>didUpdate({ state, setState, props, forceUpdate, prevProps, prevState })</code></li>
<li><code>willUnmount({ state, props })</code></li>
<li><code>children({ state, setState, props, forceUpdate })</code></li>
<li><code>render({ state, setState, props, forceUpdate })</code></li>
</ul>
<h2 id="legal"><a class="header-anchor" href="#legal" aria-hidden="true">#</a> Legal</h2>
<p>Released under MIT license.</p>
<p>Copyright © 2017-present Ryan Florence</p>     <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="https://unpkg.com/react@15.6.1/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js"></script>
    <script src="umd/react-component-component.min.js"></script>
  </body>
</html>
